using System.Collections.Generic;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Faces.Base;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestSelectPropertiesWizardStep
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            UITestUtils.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once
            UITestUtils.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        [Test]
        public void Test_Construct()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            //---------------Test Result -----------------------
            Assert.AreEqual(2, propertiesWizardStep.Controls.Count);
            Assert.IsInstanceOf(typeof (IWizardStep), propertiesWizardStep);
            Assert.IsInstanceOf(typeof (IUserControlHabanero), propertiesWizardStep);
            Assert.IsInstanceOf(typeof (IPanel), propertiesWizardStep.Controls[0]);
            Assert.IsInstanceOf(typeof (ILabel), propertiesWizardStep.Controls[1]);
            Assert.IsNotNull(propertiesWizardStep.PropertiesSelectorControl);
            Assert.IsNotNull(propertiesWizardStep.ClassSelectorControl);
            Assert.AreEqual(1, propertiesWizardStep.ClassSelectorControl.NoOfItems, "Should have an empty item");
            Assert.IsNull(propertiesWizardStep.Solution);
        }

        [Test]
        public void Test_Solution_WhenSet_ShouldPopulateCombo()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep.Solution);
            Assert.AreEqual(2, solution.AllClasses.Count);
            //---------------Execute Test ----------------------
            propertiesWizardStep.Solution = solution;
            //---------------Test Result -----------------------
            Assert.AreSame(solution, propertiesWizardStep.Solution);
            Assert.AreSame(solution.AllClasses, propertiesWizardStep.ClassSelectorControl.BusinessObjectCollection);
            Assert.AreEqual(3, propertiesWizardStep.ClassSelectorControl.NoOfItems, "Should include the empty item and 2 classes");
        }

        [Test]
        public void Test_Solution_WhenSetToNull_ShouldCreateEmptyCombo()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            propertiesWizardStep.Solution = solution;
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, solution.AllClasses.Count);
            Assert.AreSame(solution, propertiesWizardStep.Solution);
            Assert.AreSame(solution.AllClasses, propertiesWizardStep.ClassSelectorControl.BusinessObjectCollection);
            Assert.AreEqual(3, propertiesWizardStep.ClassSelectorControl.NoOfItems, "Should include the empty item and 2 classes");
            //---------------Execute Test ----------------------
            propertiesWizardStep.Solution = null;
            //---------------Test Result -----------------------
            Assert.IsNull(propertiesWizardStep.Solution);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.BusinessObjectCollection);
            Assert.AreEqual
                (1, propertiesWizardStep.ClassSelectorControl.NoOfItems, "Should include the empty item and no classes");
        }

        [Test]
        public void Test_SelectedClass_WhenSet_ShouldSelectClassInCombo()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            propertiesWizardStep.Solution = solution;
            DMClass dmClass = solution.AllClasses[1];
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep.SelectedClass);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
            //---------------Execute Test ----------------------
            propertiesWizardStep.SelectedClass = dmClass;
            //---------------Test Result -----------------------
            Assert.IsNotNull(propertiesWizardStep.SelectedClass);
            Assert.AreSame(dmClass, propertiesWizardStep.SelectedClass);
            Assert.AreSame(dmClass, propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
        }

        [Test]
        public void Test_SelectClassInSelector_ShouldSetSelectedClass()
        {
            //--------------- Set up test pack ------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            propertiesWizardStep.Solution = solution;
            DMClass dmClass = solution.AllClasses[1];

            //--------------- Test Preconditions ----------------
            Assert.IsNull(propertiesWizardStep.SelectedClass);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);

            //--------------- Execute Test ----------------------
            propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject = dmClass;
            //--------------- Test Result -----------------------
            Assert.AreSame(dmClass, propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
            Assert.IsNotNull(propertiesWizardStep.SelectedClass);
            Assert.AreSame(dmClass, propertiesWizardStep.SelectedClass);
        }

        [Test]
        public void Test_SetSelectedClass_ShouldSetPropertiesInMultiSelector()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            propertiesWizardStep.Solution = solution;
            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject();
            dmClass.Properties.CreateBusinessObject();
            IList<string> availableOptions = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep.SelectedClass);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
            Assert.AreEqual(0, availableOptions.Count);
            Assert.AreEqual(2, dmClass.Properties.Count);
            Assert.IsTrue(propertiesWizardStep.ClassSelectorControl.Enabled);
            //---------------Execute Test ----------------------
            propertiesWizardStep.SelectedClass = dmClass;
            //---------------Test Result -----------------------
            IList<string> options = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(dmClass.Properties.Count, options.Count);
            Assert.IsTrue(propertiesWizardStep.ClassSelectorControl.Enabled);
            Assert.AreEqual(dmClass.Properties.Count, propertiesWizardStep.PropertiesSelectorControl.AvailableOptionsListBox.Items.Count);
        }

        [Test]
        public void Test_SetSelectedClass_ToNull_WhenSolutionNotNull_ShouldDeSelectClassInClassSelector_AndClearPropertiesSelector()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            propertiesWizardStep.Solution = solution;
            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject();
            dmClass.Properties.CreateBusinessObject();
            propertiesWizardStep.SelectedClass = dmClass;
            IList<string> availableOptions = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(propertiesWizardStep.SelectedClass);
            Assert.IsNotNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
            Assert.AreEqual(2, availableOptions.Count);
            Assert.AreEqual(2, dmClass.Properties.Count);
            Assert.IsTrue(propertiesWizardStep.ClassSelectorControl.Enabled);
            //---------------Execute Test ----------------------
            propertiesWizardStep.SelectedClass = null;
            //---------------Test Result -----------------------
            IList<string > options = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(0, options.Count);
            Assert.IsTrue(propertiesWizardStep.ClassSelectorControl.Enabled);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
        }

        [Test]
        public void Test_SetSelectedClass_When_SolutionNotSet_ShouldSetSolutionAndDisableClassSelector()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();

            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject();
            dmClass.Properties.CreateBusinessObject();
            IList<string> availableOptions = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep.SelectedClass);
            Assert.IsNull(propertiesWizardStep.ClassSelectorControl.SelectedBusinessObject);
            Assert.AreEqual(0, availableOptions.Count);
            Assert.AreEqual(2, dmClass.Properties.Count);
            Assert.IsTrue(propertiesWizardStep.ClassSelectorControl.Enabled);
            Assert.IsNull(propertiesWizardStep.Solution);
            //---------------Execute Test ----------------------
            propertiesWizardStep.SelectedClass = dmClass;
            //---------------Test Result -----------------------
            IList<string> options = propertiesWizardStep.PropertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(dmClass.Properties.Count, options.Count);
            Assert.AreSame(dmClass.Solution, propertiesWizardStep.Solution);
            Assert.IsFalse(propertiesWizardStep.ClassSelectorControl.Enabled);
        }

        [Test]
        public void Test_InitialiseStep_DoesNothing()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            propertiesWizardStep.InitialiseStep();
            //---------------Test Result -----------------------
            //Just testing that can be initialised
        }

        [Test]
        public void Test_CanMoveBack_ShouldAlwaysBeTrue()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            propertiesWizardStep.InitialiseStep();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            bool canMoveBack = propertiesWizardStep.CanMoveBack();
            //---------------Test Result -----------------------
            Assert.IsTrue(canMoveBack);
        }

        [Test]
        public void Test_HeaderText_ShouldBe_SelectProperties()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            propertiesWizardStep.InitialiseStep();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string headerText = propertiesWizardStep.HeaderText;
            //---------------Test Result -----------------------
            Assert.AreEqual("Select Properties", headerText);
        }

        [Test]
        public void Test_CanMoveOn_WhenNoClassSelected_ShouldBeFalse()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            propertiesWizardStep.InitialiseStep();
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep.SelectedClass);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = propertiesWizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            Assert.AreEqual("You must select a SubClass before you can move on", message);
        }

        [Test]
        public void Test_CanMoveOn_WhenClassSelected_ShouldBeTrue()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            propertiesWizardStep.InitialiseStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();

            DMClass dmClass = solution.AllClasses[1];
            propertiesWizardStep.SelectedClass = dmClass;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(propertiesWizardStep.SelectedClass);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = propertiesWizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsTrue(canMoveOn);
            Assert.AreEqual("", message);
        }

        [Test]
        public void Test_CancelStep_WhenHaveSelectedProperties_ShouldUnselectTheseProperties()
        {
            //---------------Set up test pack-------------------
            SelectPropertiesWizardStep propertiesWizardStep = new SelectPropertiesWizardStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();

            DMClass dmClass = solution.AllClasses[1];
            DMProperty property = dmClass.Properties.CreateBusinessObject();
            property.PropertyName = TestUtilsShared.GetRandomString();
            DMProperty selectedProp = dmClass.Properties.CreateBusinessObject();
            selectedProp.PropertyName = TestUtilsShared.GetRandomString();
            propertiesWizardStep.SelectedClass = dmClass;
            IMultiSelector<string> propertiesSelectorControl = propertiesWizardStep.PropertiesSelectorControl;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            //---------------Assert Precondition----------------
            IList<string> availableOptions = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesSelectorControl.Model.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            //---------------Execute Test ----------------------
            propertiesWizardStep.CancelStep();
            //---------------Test Result -----------------------
            IList<string> availableOptionsAfterCancel = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(2, availableOptionsAfterCancel.Count);
            IList<string> selectedOptionsAfterCancel = propertiesSelectorControl.Model.SelectedOptions;
            Assert.AreEqual(0, selectedOptionsAfterCancel.Count);
        }
    }

}